package jp.sourceforge.akjrcp.dropsomething2;

import com.akjava.lib.swt.log.ExecuteLog;
import com.akjava.lib.swt.ui.dialog.TextDialog;

import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.ProgressBar;

import jp.sourceforge.akjrcp.akj_betas.Akj_betasPlugin;
import jp.sourceforge.akjrcp.akj_betas.Messages;
import jp.sourceforge.akjrcp.commons.ui.widget.LayoutBuilder;
import jp.sourceforge.akjrcp.commons.ui.widget.LayoutDataBuilder;
import jp.sourceforge.akjrcp.commons.ui.widget.WidgetBuilder;
import jp.sourceforge.akjrcp.ui.EditableList;
import jp.sourceforge.akjrcp.ui.EditableListData;
import jp.sourceforge.akjrcp.util.SelectionUtils;



public class DefaultListControler extends Composite implements ListControler{

	public static final int STOPPED=0;
	public static final int WORKING=1;
	public static final int STOP_NEXT=2;
	private int status=STOPPED;
	private IDropSomething2 dropSomething2;
	private Button start;
	private String execName="default";
	private TextDialog textDialog;
	public DefaultListControler(Composite parent, int style) {
		super(parent, style);
		this.setLayout(new GridLayout());
		//working
		Group working=WidgetBuilder.createGridLayoutGroup(this, SWT.NULL);
		working.setLayoutData(LayoutDataBuilder.fillHorizontalGridData());
		working.setText(Messages.getString("explorer.dd_working"));
		
		Composite cs=new Composite(working,SWT.NULL);
		cs.setLayoutData(LayoutDataBuilder.fillHorizontalGridData());
		cs.setLayout(LayoutBuilder.makeGridLayoutNoMargin(2, false));
	
		showInfo = WidgetBuilder.createButton(cs, Messages.getString("explorer.dd_show"));
	
		showInfo.setEnabled(false);
		workingName = WidgetBuilder.createLabel(cs, "");
		workingName.setLayoutData(LayoutDataBuilder.fillHorizontalGridData());
		workingName.setForeground(new Color(null,0,0,255));
		Composite cs2=new Composite(working,SWT.NULL);
		cs2.setLayoutData(LayoutDataBuilder.fillHorizontalGridData());
		cs2.setLayout(LayoutBuilder.makeGridLayoutNoMargin(2, false));
		progressBar = WidgetBuilder.createProgress(cs2);
		progressBar.setLayoutData(LayoutDataBuilder.hintGridData(300, 0));
		progressBar.setVisible(false);
		
		
		Composite bts=new Composite(cs2,SWT.NULL);
		bts.setLayout(LayoutBuilder.makeGridLayoutNoMargin(3, false));
		stopBack = WidgetBuilder.createButton(bts, Messages.getString("explorer.dd_stop_back"));
		stopBack.addSelectionListener(new SelectionListener(){
			@Override
			public void widgetDefaultSelected(SelectionEvent e) {
			}

			@Override
			public void widgetSelected(SelectionEvent e) {
				stop();
			}});
		
		cancelRemove = WidgetBuilder.createButton(bts, Messages.getString("explorer.dd_cancel_remove"));
		cancelRemove.addSelectionListener(new SelectionListener(){
			@Override
			public void widgetDefaultSelected(SelectionEvent e) {
			}

			@Override
			public void widgetSelected(SelectionEvent e) {
				dropSomething2.cancellWorking();
			}});
		stopLater = WidgetBuilder.createButton(bts, Messages.getString("explorer.dd_stop_later"));
		stopLater.addSelectionListener(new SelectionListener(){
			@Override
			public void widgetDefaultSelected(SelectionEvent e) {
			}

			@Override
			public void widgetSelected(SelectionEvent e) {
				dropSomething2.cancellWorking();
				queList.addData(currentData);
				
			}});
		
		stopBack.setEnabled(false);
		cancelRemove.setEnabled(false);
		stopLater.setEnabled(false);
		
		progressText = new Label(working,SWT.NULL);
		progressText.setLayoutData(LayoutDataBuilder.fillHorizontalGridData());
		
		//list
		Group list=WidgetBuilder.createGridLayoutGroup(this, SWT.NULL);
		list.setLayoutData(LayoutDataBuilder.fillBothGridData());
		list.setText(Messages.getString("explorer.dd_list"));
		
		
		Composite workingStatus=new Composite(list,SWT.NULL);
		workingStatus.setLayout(LayoutBuilder.makeGridLayoutNoMargin(5, false));
		statusLabel = WidgetBuilder.createLabel(workingStatus,Messages.getString( "explorer.dd_stopped"));
		statusLabel.setLayoutData(LayoutDataBuilder.hintGridData(150, 0));
		start = WidgetBuilder.createButton(workingStatus, Messages.getString("explorer.dd_start"));
		start.addSelectionListener(new SelectionListener(){
			@Override
			public void widgetDefaultSelected(SelectionEvent e) {
			}

			@Override
			public void widgetSelected(SelectionEvent e) {
				if(status==STOPPED){
					dropSomething2.startWorking();
				}else{
					start();//from pause
				}
			}});
		start.setEnabled(true);
		
		stop = WidgetBuilder.createButton(workingStatus, Messages.getString("explorer.dd_stop"));
		stop.addSelectionListener(new SelectionListener(){
			@Override
			public void widgetDefaultSelected(SelectionEvent e) {
			}

			@Override
			public void widgetSelected(SelectionEvent e) {
				stop();
			}});
		pause = WidgetBuilder.createButton(workingStatus, Messages.getString("explorer.dd_pause"));
		pause.addSelectionListener(new SelectionListener(){
			@Override
			public void widgetDefaultSelected(SelectionEvent e) {
			}

			@Override
			public void widgetSelected(SelectionEvent e) {
				pause();
			}});
		autoStart = WidgetBuilder.createCheckButton(workingStatus, Messages.getString("explorer.dd_auto"));
		autoStart.setSelection(true);
		queList = new EditableList(list,SWT.NULL,false,true);
		queList.getTable().setLayoutData(LayoutDataBuilder.fillBothGridData());
		
		//history
		Group history=WidgetBuilder.createGridLayoutGroup(this, SWT.NULL);
		history.setLayoutData(LayoutDataBuilder.fillHorizontalGridData());
		history.setText(Messages.getString("explorer.dd_history"));
		Composite hb=WidgetBuilder.createGridLayoutComposite(history, SWT.NULL, 2, false);
		hb.setLayoutData(LayoutDataBuilder.fillHorizontalGridData());
		historyTable = new HistoryListTable(hb,SWT.FULL_SELECTION);
		historyTable.getTable().setLayoutData(LayoutDataBuilder.fillHorizontalGridData());
		historyTable.addDoubleClickListener(new IDoubleClickListener(){

			

			@Override
			public void doubleClick(DoubleClickEvent event) {
				Object[] selects=SelectionUtils.getSelectObject(event.getSelection());
				if(selects.length>0){
					if(textDialog==null ||textDialog.getShell()==null){
						
					textDialog = new TextDialog(getShell(),Messages.getString("log.title"),((HistoryData)selects[0]).getLog(),true);
					textDialog.setSize(640, 480);
					textDialog.open();
					}else{
						textDialog.setText(((HistoryData)selects[0]).getLog());
					}
				}
			}});
		Composite bs=WidgetBuilder.createGridLayoutComposite(history, SWT.NULL);
		Button clear=WidgetBuilder.createButton(hb, Messages.getString("explorer.dd_clear"));
		clear.addSelectionListener(new SelectionListener(){
			@Override
			public void widgetDefaultSelected(SelectionEvent e) {
			}

			@Override
			public void widgetSelected(SelectionEvent e) {
				historyTable.clear();
			}});
		
	}

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private Button autoStart;
	private EditableList queList;
	private Label workingName;
	private HistoryListTable historyTable;
	private Button stopBack;
	private Button cancelRemove;
	private Button stopLater;
	private Button showInfo;
	private Label statusLabel;
	private EditableListData currentData;
	private Button stop;
	private Button pause;
	private Label progressText;
	private ProgressBar progressBar;

	public class ListData implements EditableListData{
		Setting setting;
		public ListData(Setting setting){
		this.setting=setting;	
		}
		@Override
		public String getLabel() {
			// TODO �����������ꂽ���\�b�h�E�X�^�u
			return setting.toString();
		}

		@Override
		public Object getValue() {
			// TODO �����������ꂽ���\�b�h�E�X�^�u
			return setting;
		}
		
	}
	
	public void addShowInfoListener(SelectionListener listener){
		showInfo.addSelectionListener(listener);
	}

	@Override
	public void addSetting(Setting setting) {
		queList.addData(new ListData(setting));
		
	}

	@Override
	public boolean hasNext() {
		return status==WORKING && queList.size()>0;
	}

	@Override
	public Setting next() {
		currentData = queList.popData();
		//initialize
		setProgress(0);
		workingName.setText(currentData.getLabel());
		
		//enableButtons.
		showInfo.setEnabled(true);
		stopBack.setEnabled(true);
		cancelRemove.setEnabled(true);
		stopLater.setEnabled(true);
		
		Setting setting=(Setting) currentData.getValue();
		
		
		//i'm not sure 
		ExecuteLog executeLog=new ExecuteLog(getExecName(),setting.toString());
		Akj_betasPlugin.getDefault().addExecuteLog(executeLog);//TODO interface
		((AbstractFFMpegDropSomething2)dropSomething2).setExecuteLog(executeLog);//TODO add method to interface?
		
		return setting;
	}

	@Override
	public void setProgress(int value) {
		progressBar.setSelection(value);
	}

	@Override
	public boolean isAutoStart() {
		return autoStart.getSelection();
	}

	@Override
	public boolean isWorking() {
		return status==WORKING;
	}

	public void cancelled(Setting setting) {
		clearWorking();
		
		ExecuteLog executeLog=getExecuteLog();
		if(executeLog!=null){
			executeLog.setResult(ExecuteLog.STATUS_CANCEL);
		}
	}
	
	public ExecuteLog getExecuteLog(){
		return ((AbstractFFMpegDropSomething2)dropSomething2).getExecuteLog();
	}
	
	@Override
	public void faild(Setting setting) {
		
		clearWorking();
		HistoryData hdata=new HistoryData(setting.toString(),Messages.getString("explorer.dd_faild"),System.currentTimeMillis());
		historyTable.addHistory(hdata);
		
		ExecuteLog executeLog=getExecuteLog();
		if(executeLog!=null){
			executeLog.setResult(ExecuteLog.STATUS_NG);
			hdata.setLog(executeLog.getLogText());
		}
	}

	@Override
	public void successed(Setting setting) {
		clearWorking();
		HistoryData hdata=new HistoryData(setting.toString(),Messages.getString("explorer.dd_successed"),System.currentTimeMillis());
		historyTable.addHistory(hdata);
		
		ExecuteLog executeLog=getExecuteLog();
		if(executeLog!=null){
			executeLog.setResult(ExecuteLog.STATUS_OK);
			hdata.setLog(executeLog.getLogText());
		}
	
	}
	
	private void clearWorking(){
		workingName.setText("");
		//disable buttons
		stopBack.setEnabled(false);
		cancelRemove.setEnabled(false);
		stopLater.setEnabled(false);
		showInfo.setEnabled(false);
		
	}
	//called from before Execute
	public void start(){
		
		status=WORKING;
		statusLabel.setText(Messages.getString("explorer.dd_working"));
		start.setEnabled(false);
		stop.setEnabled(true);
		pause.setEnabled(true);
		progressBar.setVisible(true);
	}
	public void finish(){
		status=STOPPED;
		statusLabel.setText(Messages.getString("explorer.dd_stopped"));
		start.setEnabled(true);
		stop.setEnabled(false);
		pause.setEnabled(false);
		progressBar.setVisible(false);
	}

	private void stop(){
		status=STOPPED;
		//finish();//maybe called twice from loop
		dropSomething2.cancellWorking();//for delete old files.
		queList.addData(currentData,0);//task back
	}
	
	private void pause(){
		start.setEnabled(true);
		status=STOP_NEXT; //stop automatic
		statusLabel.setText(Messages.getString("explorer.dd_stop_next"));
	}

	public IDropSomething2 getDropSomething2() {
		return dropSomething2;
	}

	public void setDropSomething2(IDropSomething2 dropSomething2) {
		this.dropSomething2 = dropSomething2;
	}

	@Override
	public Object getControler() {
		
		return this;
	}

	@Override
	public void setProgressText(String text) {
		progressText.setText(text);
	}

	public EditableList getQueList() {
		return queList;
	}

	public EditableListData getCurrentData() {
		return currentData;
	}

	public String getExecName() {
		return execName;
	}

	public void setExecName(String execName) {
		this.execName = execName;
	}
}
